Skip to content

RBAC 权限管理(思路)

注意

  1. JWT 中不要存储太多信息
  2. 关于权限:只有添加了权限守卫的接口才会被拦截
  3. 登录后返回用户信息和角色信息,此角色信息只是给前端用的,后端的角色权限还需要从 jwt 中解析用户信息后再次请求接口查询角色信息(此步生产环境则需要在 redis 中缓存)

实体表字段设计

  1. 用户表

存储用户基础信息,核心字段包含登录凭证、个人信息、状态等

shell
CREATE TABLE `sys_user` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `username` varchar(50) NOT NULL COMMENT '用户名(唯一)',
  `password` varchar(255) NOT NULL COMMENT '密码(BCrypt/SHA256加密存储)',
  `nickname` varchar(50) DEFAULT '' COMMENT '用户昵称',
  `email` varchar(100) DEFAULT '' COMMENT '邮箱',
  `phone` varchar(20) DEFAULT '' COMMENT '手机号',
  `avatar` varchar(255) DEFAULT '' COMMENT '头像URL',
  `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:0=禁用,1=启用',
  `is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '软删除:0=未删,1=已删',
  `last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `create_by` bigint DEFAULT NULL COMMENT '创建人ID',
  `update_by` bigint DEFAULT NULL COMMENT '更新人ID',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_username` (`username`),
  UNIQUE KEY `uk_phone` (`phone`) USING BTREE,
  UNIQUE KEY `uk_email` (`email`) USING BTREE,
  KEY `idx_status` (`status`),
  KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表';
  1. 角色表

存储角色信息,角色是权限的集合(如「超级管理员」「普通用户」「运营人员」)。

shell
CREATE TABLE `sys_role` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '角色ID',
  `role_name` varchar(50) NOT NULL COMMENT '角色名称(唯一)',
  `role_code` varchar(50) NOT NULL COMMENT '角色编码(唯一,如ADMIN/USER/OPERATOR)',
  `description` varchar(255) DEFAULT '' COMMENT '角色描述',
  `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:0=禁用,1=启用',
  `is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '软删除:0=未删,1=已删',
  `sort` int DEFAULT 0 COMMENT '排序(用于前端展示)',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_role_name` (`role_name`),
  UNIQUE KEY `uk_role_code` (`role_code`),
  KEY `idx_status` (`status`),
  KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统角色表';
  1. 权限表

存储最小粒度的权限(如「用户新增」「角色删除」「菜单查看」),支持层级(父权限)。

shell
CREATE TABLE `sys_permission` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '权限ID',
  `perm_name` varchar(50) NOT NULL COMMENT '权限名称',
  `perm_code` varchar(100) NOT NULL COMMENT '权限编码(唯一,如sys:user:add)',
  `module` varchar(50) DEFAULT '' COMMENT '所属模块(如系统管理/用户管理)',
  `action` varchar(20) DEFAULT '' COMMENT '操作类型(add/edit/delete/query)',
  `url` varchar(255) DEFAULT '' COMMENT '关联接口/页面URL',
  `parent_id` bigint DEFAULT 0 COMMENT '父权限ID(0=顶级权限)',
  `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:0=禁用,1=启用',
  `is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '软删除:0=未删,1=已删',
  `sort` int DEFAULT 0 COMMENT '排序(用于前端菜单展示)',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_perm_code` (`perm_code`),
  KEY `idx_parent_id` (`parent_id`),
  KEY `idx_status` (`status`),
  KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统权限表';

NestJS 中 RBAC + 菜单权限方案

RBAC(基于角色的访问控制)是企业级应用中最常用的权限模型,核心思想是用户 - 角色 - 权限的三层解耦;而菜单权限是 RBAC 的核心落地场景之一(前端动态渲染菜单、后端校验接口 / 按钮权限)

shell
用户 角色 菜单(权限),三层解耦,便于权限批量管理

1 个用户可关联多个角色,1 个角色可分配给多个用户;
1 个角色可关联多个菜单 / 权限,1 个菜单 / 权限可分配给多个角色;
用户的最终权限 = 其所有角色关联的菜单 / 权限的并集。

给用户赋予权限,不能直接给用户赋予权限,而是中间需要一个桥梁,桥梁便是角色
通过给用户分配角色,从而获得这个角色的批量权限

核心概念与整体架构

  1. RBAC 三层模型(核心) 用户(User):系统操作者,一个用户可关联多个角色(多对多)。 角色(Role):权限的集合,比如「管理员」「普通用户」「运营」,一个角色可关联多个权限(多对多)。 权限(Permission):最小权限单元,分为两类: 「菜单 / 按钮权限」:控制前端菜单显示、按钮禁用(如 menu:user:list、button:user:add); 「接口权限」:控制后端接口访问(如 api:user:delete)。
  2. 整体架构
shell
用户登录 JWT 认证 权限守卫(Guard)→ 解析用户角色 匹配权限(装饰器标记)→ 允许/拒绝访问

                                    菜单服务 筛选用户可访问菜单 返回前端渲染